package com.example.app.view;

import android.app.Application;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.view.View;
import androidx.annotation.Nullable;
import com.example.app.R;
import com.example.app.api.ParkingService;
import com.example.app.config.RetrofitClient;
import com.example.app.manager.TokenManager;
import com.google.gson.Gson;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class ParkingMapView extends View {

    // 默认配置
    private static final int DEFAULT_ROWS = 6;
    private static final int DEFAULT_COLS = 8;
    private static final int DEFAULT_ROAD_WIDTH_DP = 16;
    // 偏移常量
    private static final float PATH_OFFSET_DP = 15;

    // 颜色配置
    private int freeColor = Color.parseColor("#4CAF50");
    private int occupiedColor = Color.parseColor("#F44336");
    private int roadColor = Color.parseColor("#9E9E9E");
    private int entranceColor = Color.parseColor("#2196F3");
    private int pathColor = Color.parseColor("#FFC107");

    // 尺寸参数
    private float roadWidthPx;
    private float slotWidth, slotHeight;

    // 布局数据
    private int rows = DEFAULT_ROWS;
    private int cols = DEFAULT_COLS;
    private int[][] slotStates;
    private final Random random = new Random();

    private TokenManager tokenManager;
    private RetrofitClient retrofitClient;
    private Context appContext;

    // 导航相关
    private List<PointF> navigationPath = new ArrayList<>();
    private int targetSlot = -1;

    // 绘制工具
    private Paint slotPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private Paint roadPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private Paint textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private Paint entrancePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private Paint pathPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private Paint arrowPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

    // 用于存储plateParkIds
    private List<String> plateParkIds = new ArrayList<>();

    public ParkingMapView(Context context) {
        super(context);
        init(context, null);
    }

    public ParkingMapView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public ParkingMapView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs) {
        this.appContext = context.getApplicationContext();
        retrofitClient = RetrofitClient.getInstance((Application) appContext);
        tokenManager = retrofitClient.getTokenManager();

        // 读取XML属性
        if (attrs != null) {
            TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.ParkingMapView);
            rows = ta.getInt(R.styleable.ParkingMapView_rows, DEFAULT_ROWS);
            cols = ta.getInt(R.styleable.ParkingMapView_cols, DEFAULT_COLS);
            freeColor = ta.getColor(R.styleable.ParkingMapView_freeColor, freeColor);
            occupiedColor = ta.getColor(R.styleable.ParkingMapView_occupiedColor, occupiedColor);
            roadColor = ta.getColor(R.styleable.ParkingMapView_roadColor, roadColor);
            entranceColor = ta.getColor(R.styleable.ParkingMapView_entranceColor, entranceColor);
            roadWidthPx = ta.getDimension(R.styleable.ParkingMapView_roadWidth,
                    dpToPx(DEFAULT_ROAD_WIDTH_DP));
            ta.recycle();
        }

        // 初始化绘制参数
        getParkStatus();
        configurePaints();
        generateSlotStates();
    }

    public void getParkStatus() {
        ParkingService parkingService = retrofitClient.getAuthService(ParkingService.class);
        Call<ResponseBody> call = parkingService.getParkStatus();

        call.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                try {
                    String responseBody = response.body() != null? response.body().string() : "";
                    if (response.isSuccessful()) {
                        Gson gson = new Gson();
                        StatusResponse statusResponse = gson.fromJson(responseBody, StatusResponse.class);
                        if (statusResponse != null) {
                            plateParkIds = statusResponse.plateParkIds;
                        }
                        System.out.println("请求成功，响应体: " + responseBody);
                        invalidate();
                    } else {
                        // 处理失败的响应
                        System.out.println("请求失败，状态码: " + response.code());
                    }
                } catch (IOException e) {
                    // 记录错误日志或者进行提示
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                // 处理请求失败的情况
                System.out.println("请求失败，错误信息: " + t.getMessage());
            }
        });
    }

    private void configurePaints() {
        // 车位绘制
        slotPaint.setStyle(Paint.Style.FILL);

        // 道路绘制
        roadPaint.setColor(roadColor);
        roadPaint.setStyle(Paint.Style.FILL);

        // 文字绘制
        textPaint.setColor(Color.WHITE);
        textPaint.setTextAlign(Paint.Align.CENTER);
        textPaint.setTextSize(dpToPx(12));

        // 入口标识
        entrancePaint.setColor(entranceColor);
        entrancePaint.setStyle(Paint.Style.FILL);

        // 路径绘制
        pathPaint.setColor(pathColor);
        pathPaint.setStyle(Paint.Style.STROKE);
        pathPaint.setStrokeWidth(dpToPx(4));
        pathPaint.setStrokeJoin(Paint.Join.ROUND);

        // 方向箭头
        arrowPaint.setColor(pathColor);
        arrowPaint.setStyle(Paint.Style.FILL);
    }

    private float dpToPx(float dp) {
        return dp * getResources().getDisplayMetrics().density;
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        calculateDimensions();
    }

    private void calculateDimensions() {
        float contentWidth = getWidth() - getPaddingLeft() - getPaddingRight();
        float contentHeight = getHeight() - getPaddingTop() - getPaddingBottom();

        // 计算车位实际尺寸（含四周道路）
        slotWidth = (contentWidth - (cols + 1) * roadWidthPx) / cols;
        slotHeight = (contentHeight - (rows + 1) * roadWidthPx) / rows;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawRoadGrid(canvas);
        drawParkingSlots(canvas);
        drawEntrance(canvas);
        drawNavigationPath(canvas);
    }

    private void drawRoadGrid(Canvas canvas) {
        // 绘制横向道路
        for (int i = 0; i <= rows; i++) {
            float y = getPaddingTop() + i * (slotHeight + roadWidthPx);
            canvas.drawRect(
                    getPaddingLeft(), y,
                    getWidth() - getPaddingRight(), y + roadWidthPx,
                    roadPaint
            );
        }

        // 绘制纵向道路
        for (int i = 0; i <= cols; i++) {
            float x = getPaddingLeft() + i * (slotWidth + roadWidthPx);
            canvas.drawRect(
                    x, getPaddingTop(),
                    x + roadWidthPx, getHeight() - getPaddingBottom(),
                    roadPaint
            );
        }
    }

    private void drawParkingSlots(Canvas canvas) {
        for (int row = 0; row < rows; row++) {
            for (int col = 0; col < cols; col++) {
                int slotNumber = row * cols + col + 1;
                String slotNumberStr = String.valueOf(slotNumber);
                boolean isOccupied = plateParkIds.contains(slotNumberStr);
                drawSingleSlot(canvas, row, col, isOccupied);
            }
        }
    }

    private void drawSingleSlot(Canvas canvas, int row, int col, boolean isOccupied) {
        float left = getPaddingLeft() + (col + 1) * roadWidthPx + col * slotWidth;
        float top = getPaddingTop() + (row + 1) * roadWidthPx + row * slotHeight;

        // 绘制车位背景
        slotPaint.setColor(isOccupied? occupiedColor : freeColor);
        canvas.drawRect(left, top, left + slotWidth, top + slotHeight, slotPaint);

        // 绘制车位编号
        String slotNumber = String.valueOf(row * cols + col + 1);
        float textY = top + slotHeight / 2 + textPaint.getTextSize() / 3;
        canvas.drawText(slotNumber, left + slotWidth / 2, textY, textPaint);
    }

    private void drawEntrance(Canvas canvas) {
        float entranceShift = dpToPx(PATH_OFFSET_DP);

        float entranceX = getPaddingLeft() + cols * (slotWidth + roadWidthPx) + entranceShift;
        float entranceY = getPaddingTop() + rows * (slotHeight + roadWidthPx);

        // 绘制入口箭头
        Path arrow = new Path();
        arrow.moveTo(entranceX - roadWidthPx / 2, entranceY - roadWidthPx / 2);
        arrow.lineTo(entranceX - roadWidthPx, entranceY - roadWidthPx / 2);
        arrow.lineTo(entranceX - roadWidthPx / 2, entranceY - roadWidthPx);
        arrow.close();
        canvas.drawPath(arrow, entrancePaint);

        // 绘制入口文字
        canvas.drawText("入口", entranceX - roadWidthPx / 2,
                entranceY - roadWidthPx / 2 + textPaint.getTextSize() + dpToPx(4), textPaint);
    }

    private PointF adjustPoint(PointF point) {
        float offset = dpToPx(PATH_OFFSET_DP);
        return new PointF(point.x + offset, point.y + offset);
    }

    private void drawNavigationPath(Canvas canvas) {
        if (navigationPath.size() < 2) return;

        // 绘制路径线
        Path path = new Path();
        List<PointF> adjustedPoints = new ArrayList<>();

        for (PointF point : navigationPath) {
            PointF adjustedPoint = adjustPoint(point);
            adjustedPoints.add(adjustedPoint);

            if (adjustedPoints.size() == 1) {
                path.moveTo(adjustedPoint.x, adjustedPoint.y);
            } else {
                path.lineTo(adjustedPoint.x, adjustedPoint.y);
            }
        }
        canvas.drawPath(path, pathPaint);

        // 只在最后一段线段上绘制箭头
        if (adjustedPoints.size() >= 2) {
            PointF start = adjustedPoints.get(adjustedPoints.size() - 2);
            PointF end = adjustedPoints.get(adjustedPoints.size() - 1);
            drawDirectionArrow(canvas, start, end);
        }
    }

    private void drawDirectionArrow(Canvas canvas, PointF start, PointF end) {
        float dx = end.x - start.x;
        float dy = end.y - start.y;
        float distance = (float) Math.sqrt(dx * dx + dy * dy);

        // 如果两点距离太短，不绘制箭头
        if (distance < dpToPx(10)) return;

        // 计算箭头的位置（在线段上距离终点1/3处）
        float arrowPosition = 2f / 3f;
        float arrowX = start.x + dx * arrowPosition;
        float arrowY = start.y + dy * arrowPosition;

        // 计算箭头角度
        float angle = (float) Math.atan2(dy, dx);
        float arrowSize = dpToPx(8);

        // 绘制箭头
        Path arrow = new Path();
        arrow.moveTo(arrowX, arrowY);
        arrow.lineTo(arrowX - arrowSize * (float) Math.cos(angle - Math.PI / 6),
                arrowY - arrowSize * (float) Math.sin(angle - Math.PI / 6));
        arrow.lineTo(arrowX - arrowSize * (float) Math.cos(angle + Math.PI / 6),
                arrowY - arrowSize * (float) Math.sin(angle + Math.PI / 6));
        arrow.close();
        canvas.drawPath(arrow, arrowPaint);
    }

    public void setNavigationTarget(int slotNumber) {
        if (slotNumber < 1 || slotNumber > rows * cols) {
            navigationPath.clear();
            invalidate();
            return;
        }

        targetSlot = slotNumber;
        calculateNavigationPath();
        invalidate();
    }

    private void calculateNavigationPath() {
        navigationPath.clear();

        // 入口道路中心点（右下角）
        PointF entranceRoad = new PointF(
                getPaddingLeft() + cols * (slotWidth + roadWidthPx) - roadWidthPx / 2,
                getPaddingTop() + rows * (slotHeight + roadWidthPx) - roadWidthPx / 2
        );

        // 目标车位对应的道路中心点
        int targetRow = (targetSlot - 1) / cols;
        int targetCol = (targetSlot - 1) % cols;
        PointF targetRoad = new PointF(
                getPaddingLeft() + (targetCol + 1) * (slotWidth + roadWidthPx) - roadWidthPx / 2,
                getPaddingTop() + (targetRow + 1) * (slotHeight + roadWidthPx) - roadWidthPx / 2
        );

        // 路径规划（始终沿道路中心线）
        navigationPath.add(entranceRoad);

        // 垂直移动到目标行道路
        navigationPath.add(new PointF(entranceRoad.x, targetRoad.y));

        // 水平移动到目标列道路
        navigationPath.add(targetRoad);

        // 移动到车位前道路中心
        PointF roadCenterBeforeSlot = new PointF(
                targetRoad.x,
                targetRoad.y - roadWidthPx / 2 - slotHeight / 2
        );
        navigationPath.add(roadCenterBeforeSlot);

        // 新增：从道路中心到车位前的水平线段，指向车位
        PointF slotPosition = new PointF(
                getPaddingLeft() + (targetCol + 1) * roadWidthPx + targetCol * slotWidth + slotWidth / 2,
                roadCenterBeforeSlot.y
        );
        navigationPath.add(slotPosition);
    }

    public void clearNavigation() {
        navigationPath.clear();
        invalidate();
    }

    private void generateSlotStates() {
        slotStates = new int[rows][cols];
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                slotStates[i][j] = random.nextFloat() < 0.3? 1 : 0;
            }
        }
    }

    // 公共访问方法
    public int getTotalSlots() {
        return rows * cols;
    }

    public int getRows() {
        return rows;
    }

    public int getCols() {
        return cols;
    }

    public List<String> getPlateParkIds() {
        return plateParkIds;
    }
}

class StatusResponse {
    boolean success;
    List<String> plateParkIds;
    String message;
}
